package org.upfrost;

import java.util.List;

import junit.framework.Assert;

import org.junit.Test;
import org.upfrost.mapping.classes.TestClass2;
import org.upfrost.mapping.classes.TestClass3;


public class QueryJoinsTest extends BaseTestClass
{
	@Test
	public void testJoin2MappedClassesSize()
	{
		injectTestClass2();
		injectTestClass3();
		
		List<Object[]> join = m_session.createQuery("select * from test2,test3 where test2.id=test3.id").asArray(TestClass2.class,TestClass3.class).list();
		Assert.assertEquals(100, join.size());
	}

	@Test
	public void testJoin2MappedClassesValues()
	{
		injectTestClass2();
		injectTestClass3();
		
		for (int i=0; i<100; i++)
		{
			Object[] sjoin = m_session.createQuery("select * from test2,test3 where test2.id=test3.id and test2.id=?").param(i+1).asArray(TestClass2.class,TestClass3.class).single();

			Assert.assertNotNull(sjoin);
			Assert.assertEquals(2, sjoin.length);
			Assert.assertTrue(sjoin[0] instanceof TestClass2);
			Assert.assertTrue(sjoin[1] instanceof TestClass3);
			Assert.assertEquals(i+1, ((TestClass2)sjoin[0]).getId());
			Assert.assertEquals(i+1, ((TestClass3)sjoin[1]).getId());
			Assert.assertEquals("test2:"+(i+1), ((TestClass2)sjoin[0]).getStrValue());
			Assert.assertEquals("test3:"+(i+1), ((TestClass3)sjoin[1]).getStrValue());
		}
	}

	public void testJoin2NonMappedColumns()
	{
		injectTestClass2();
		injectTestClass3();
		
		for (int i=0; i<100; i++)
		{
			Object[] sjoin = m_session.createQuery("select test2.id, test2.\"value\", test3.\"value\" from test2,test3 where test2.id=test3.id and test2.id=?").param(i+1).asArray(Integer.class, String.class,String.class).single();

			Assert.assertNotNull(sjoin);
			Assert.assertEquals(3, sjoin.length);
			Assert.assertTrue(sjoin[0] instanceof Integer);
			Assert.assertTrue(sjoin[1] instanceof String);
			Assert.assertTrue(sjoin[2] instanceof String);
			Assert.assertEquals(new Integer(i+1), (Integer)sjoin[0]);
			Assert.assertEquals("test2:"+(i+1), sjoin[1].toString());
			Assert.assertEquals("test3:"+(i+1), sjoin[2].toString());
		}
	}

	public void testJoinMappedAndNonMappedColumnsGoodOrder()
	{
		injectTestClass2();
		injectTestClass3();
		
		for (int i=0; i<100; i++)
		{
			Object[] sjoin = m_session.createQuery("select test3.\"value\", test2.*  from test2,test3 where test2.id=test3.id and test2.id=?").param(i+1).asArray(String.class, TestClass2.class).single();

			Assert.assertNotNull(sjoin);
			Assert.assertEquals(2, sjoin.length);
			Assert.assertTrue(sjoin[0] instanceof String);
			Assert.assertTrue(sjoin[1] instanceof TestClass2);
			Assert.assertEquals("test3:"+(i+1), sjoin[0].toString());
			Assert.assertEquals("test2:"+(i+1), ((TestClass2)sjoin[1]).getStrValue());
		}
	}

	public void testJoinMappedAndNonMappedColumnsWrongOrder()
	{
		injectTestClass2();
		injectTestClass3();
		
		for (int i=0; i<10; i++)
		{
			try {
				Object[] sjoin = m_session.createQuery("select test2.*, test3.\"value\"  from test2,test3 where test2.id=test3.id and test2.id=?").param(i+1).asArray(String.class, TestClass2.class).single();
				Assert.fail();
			} catch (Exception exc)
			{
				// OK
			}
		}
	}

	public void testJoinNonMappedColumnsByName()
	{
		injectTestClass2();
		injectTestClass3();
		
		for (int i=0; i<10; i++)
		{
			String sqlquery = "select test2.id, test3.\"value\" str from test2,test3 where test2.id=test3.id and test2.id=?"; 
			Object[] sjoin = m_session.createQuery(sqlquery).param(i+1).asClass(Integer.class).join("str").single();
			
			Assert.assertNotNull(sjoin);
			Assert.assertEquals(2, sjoin.length);
			Assert.assertTrue(sjoin[0] instanceof Integer);
			Assert.assertTrue(sjoin[1] instanceof String);
			Assert.assertEquals("test3:"+(i+1), sjoin[1].toString());
			Assert.assertEquals(new Integer(i+1), ((Integer)sjoin[0]));
			
		}
	}

	
}
